package uk.ac.bath.genetic.tests;
import uk.ac.bath.genetic.bool.Int;
import uk.ac.bath.genetic.bool.Diff;
import uk.ac.bath.genetic.bool.Link;
import uk.ac.bath.genetic.bool.Cmp;
import uk.ac.bath.genetic.bool.Mult;

import uk.ac.bath.genetic.bool.X;
import uk.ac.bath.genetic.bool.LogicalMachine;
import uk.ac.bath.genetic.base.Value;

import java.io.*;
import java.util.*;
import uk.ac.bath.genetic.base.Operator;
import uk.ac.bath.genetic.base.Pallete;
import uk.ac.bath.genetic.base.PalleteIF;

class TestMachine {


    static Vector<Operator> ops = new Vector<Operator>();
    static PalleteIF pallete;
    
    static int n=10;
    public static void main(String args[]) throws Exception {
	// 	BufferedReader bin;
	// 	if (args.length > 1) {
	// 	    File file = new File(args[1]);
	// 	    FileReader reader= new FileReader(file);
	// 	    bin = new BufferedReader( reader );
	// 	} else {
	// 	    bin=new BufferedReader(new InputStreamReader(System.in));	
	// 	}

	
	//         ops.add(new And());
	//         ops.add(new Or());
	//         ops.add(new Not());
	ops.add(new Link());
	// 	// 	ops.add(new X());
	ops.add(new Mult());
	ops.add(new Cmp());
	ops.add(new Diff());
	//         ops.add(new On());
	//         ops.add(new Off());
	ops.add(new Int());
	ops.add(new X());

	n=Integer.parseInt(args[0]);
	LogicalMachine m= new LogicalMachine(n,new Pallete(ops,new Value(0.0)));

	write(m);
	test1(m);


    }


    public static void write(LogicalMachine m) {
    
	StringWriter w = new StringWriter();
	m.toString(w);

	System.out.println(w.toString());
    }

    public static void test1(LogicalMachine m) throws Exception {

	BufferedReader bin=new BufferedReader(new InputStreamReader(System.in));	
	System.out.println(" in=" + m.getState().toString());

	Value v = new Value(0.0); // (Value) m.getProtoValue().clone();
	

	char c='1';
	int count=0;
	Date time1=null;
	
	while(true) {
	    if (c != 'B') {
		String s=bin.readLine();
	    
		if (s.length() != 0) c=s.charAt(0);

		if (c == 'M') {
		    m.mutate();
		    write(m);
		} else if (c == 'N') {
		    m= new LogicalMachine(n,pallete);
		    write(m);
		} else if (c == 'C') {
		    m=(LogicalMachine)(m.clone());
		    write(m);
		} else if (c == 'Q') {
		    break;
		}else if (c == '1') {
		    m.getState().at(0).set(1);
		} else if (c == '0') {
		    m.getState().at(0).set(0);
		} else if (c == 'B' ) {
		    time1=new Date();
		}
	    }

	    m.tick();
	    if (c != 'B') System.out.println("out="+ m.getState().toString());
	    if (count++ == 1000) {
		c = 'X';
		count=0;
		long mSec = (new Date()).getTime() - time1.getTime();
		System.out.println( " tick rate = " + 1.0/(mSec/1000.0/1000.0) + " Hz ");
	    }

	}
    }

}
